package main.java.com.gdkj.dto.socket;

import java.io.Serializable;
import java.util.Arrays;

public class GameDataPacket implements Serializable {
    private byte startCode;       // 开始码
    private byte dataLength;      // 数据长度
    private byte commandId;       // 指令ID
    private byte commandType;     // 指令类型
    private byte[] commandData;   // 指令数据
    private byte checkBit;        // 校验位
    private byte endCode;         // 结束码

    // 构造函数
    public GameDataPacket(byte startCode, byte dataLength, byte commandId, byte commandType, byte[] commandData, byte checkBit, byte endCode) {
        this.startCode = startCode;
        this.dataLength = dataLength;
        this.commandId = commandId;
        this.commandType = commandType;
        this.commandData = commandData;
        this.checkBit = checkBit;
        this.endCode = endCode;
    }

    public GameDataPacket(byte startCode, byte dataLength, byte commandId, byte commandType, byte[] commandData, byte endCode) {
        this.startCode = startCode;
        this.dataLength = dataLength;
        this.commandId = commandId;
        this.commandType = commandType;
        this.commandData = commandData;
        this.endCode = endCode;

        // 计算校验位
        Integer checkBitInt = dataLength + commandId + commandType;
        if (commandData != null && commandData.length > 0) {
            for (byte dataByte : commandData) {
                checkBitInt += dataByte;
            }
        }
        this.checkBit = checkBitInt.byteValue();
    }

    // Getters and Setters
    public byte getStartCode() {
        return startCode;
    }

    public void setStartCode(byte startCode) {
        this.startCode = startCode;
    }

    public byte getDataLength() {
        return dataLength;
    }

    public void setDataLength(byte dataLength) {
        this.dataLength = dataLength;
    }

    public byte getCommandId() {
        return commandId;
    }

    public void setCommandId(byte commandId) {
        this.commandId = commandId;
    }

    public byte getCommandType() {
        return commandType;
    }

    public void setCommandType(byte commandType) {
        this.commandType = commandType;
    }

    public byte[] getCommandData() {
        return commandData;
    }

    public void setCommandData(byte[] commandData) {
        this.commandData = commandData;
    }

    public byte getCheckBit() {
        return checkBit;
    }

    public void setCheckBit(byte checkBit) {
        this.checkBit = checkBit;
    }

    public byte getEndCode() {
        return endCode;
    }

    public void setEndCode(byte endCode) {
        this.endCode = endCode;
    }

    // 将DataPacket对象转换为字节数组
    public byte[] toByteArray() {
        int dateLength = 0;
        if (commandData != null && commandData.length > 0) {
            dateLength = commandData.length;
        }
        byte[] result = new byte[6 + dateLength];
        result[0] = startCode;
        result[1] = dataLength;
        result[2] = commandId;
        result[3] = commandType;
        if (commandData != null && commandData.length > 0) {
            System.arraycopy(commandData, 0, result, 4, commandData.length);
        }
        result[4 + dateLength] = checkBit;
        result[5 + dateLength] = endCode;
        return result;
    }

    // 从字节数组转换为DataPacket对象
    public static GameDataPacket fromByteArray(byte[] byteArray) {
        if (byteArray.length < 7) {
            throw new IllegalArgumentException("byte array is too short");
        }

        byte startCode = byteArray[0];
        byte dataLength = byteArray[1];
        byte commandId = byteArray[2];
        byte commandType = byteArray[3];
        byte[] commandData = Arrays.copyOfRange(byteArray, 4, 4 + dataLength - 3);
        byte checkBit = byteArray[4 + dataLength - 3];
        byte endCode = byteArray[5 + dataLength - 3];

        return new GameDataPacket(startCode, dataLength, commandId, commandType, commandData, checkBit, endCode);
    }

    // 重写toString方法，用于打印数据包的详细信息
    @Override
    public String toString() {
        if (commandData != null && commandData.length > 0) {
            return "DataPacket{" +
                    "startCode=" + startCode +
                    ", dataLength=" + dataLength +
                    ", commandId=" + commandId +
                    ", commandType=" + commandType +
                    ", commandData=" + Arrays.toString(commandData) +
                    ", checkBit=" + checkBit +
                    ", endCode=" + endCode +
                    '}';
        }
        return "DataPacket{" +
                "startCode=" + startCode +
                ", dataLength=" + dataLength +
                ", commandId=" + commandId +
                ", commandType=" + commandType +
                ", checkBit=" + checkBit +
                ", endCode=" + endCode +
                '}';
    }
}